package com.simple.mqtt.common.task;

import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.mqtt.MqttMessage;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
import io.netty.handler.codec.mqtt.MqttQoS;

import java.util.concurrent.ScheduledExecutorService;

/**
 * Handles QoS 2 level publish message retransmission mechanism
 * Manages PUBREC message acknowledgment and retransmission for exactly-once delivery
 */
public final class MqttPendingQos2Publish extends AbstractMqttPendingMessage<MqttMessage> {

    /** Incoming publish message for QoS 2 processing */
    private final MqttPublishMessage incomingPublish;

    /**
     * Constructor
     * @param incomingPublish incoming publish message
     * @param originalMessage original message for retransmission
     */
    public MqttPendingQos2Publish(MqttPublishMessage incomingPublish, MqttMessage originalMessage) {
        super(MqttQoS.EXACTLY_ONCE, new RetryProcessor<>());
        this.incomingPublish = incomingPublish;
        this.retryProcessor.setOriginalMessage(originalMessage);
    }

    /**
     * Start PUBREC retransmission timer
     * @param taskService scheduled task service
     * @param ctx channel context
     */
    public void startPubRecRetransmitTimer(ScheduledExecutorService taskService, ChannelHandlerContext ctx) {
        startRetransmissionTimer(taskService, ctx,
                (header, msg) -> new MqttMessage(header, msg.variableHeader()),
                "PubRec");
    }

    /**
     * Called when PUBREL message is received
     * Stops PUBREC retransmission timer
     */
    public void onPubRelReceived() {
        stopRetransmission();
    }
}